package com.jh.netty.server;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

import java.nio.ByteOrder;

/**
 * 指令
 * maxFrameLength：最大帧长度。也就是可以接收的数据的最大长度。如果超过，此次数据会被丢弃。
 * lengthFieldOffset：长度域偏移。就是说数据开始的几个字节可能不是表示数据长度，需要后移几个字节才是长度域。
 * lengthFieldLength：长度域字节数。用几个字节来表示数据长度。
 * lengthAdjustment：数据长度修正。因为长度域指定的长度可以使header+body的整个长度，也可以只是body的长度。如果表示header+body的整个长度，那么我们需要修正数据长度。
 * initialBytesToStrip：跳过的字节数。如果你需要接收header+body的所有数据，此值就是0，如果你只想接收body数据，那么需要跳过header所占用的字节数。
 *
 * 引导码   设备码  控制器地址码   数据包长度   数据包       校验码
 * 2byte    1byte    1byte        2byte    (长度可变)    2byte
 */
public class InstructionLengthFieldBasedFrameDecoder extends LengthFieldBasedFrameDecoder {

    private static final int lengthFieldOffset = 4;

    private static final int lengthFieldLength = 2;

    public InstructionLengthFieldBasedFrameDecoder() {
        super(Integer.MAX_VALUE, lengthFieldOffset, lengthFieldLength, 0, 0);
    }

    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
//        System.out.println("===>>>:" + ByteBufUtil.hexDump(in));
        ByteBuf newIn = (ByteBuf) super.decode(ctx,in);
//        newIn.readByte();
        // 引导码 2个字节
        ByteBuf yindaoma = newIn.readBytes(2);
        System.out.println("=引导码==>>> ：" + ByteBufUtil.hexDump(yindaoma));
        // 设备码 1个字节
        byte shebeima = newIn.readByte();
        System.out.println("设备码===>>> ：" + shebeima);
        // 控制器码 1个字节
        byte kongzhiqi = newIn.readByte();
        System.out.println("=控制器码==>>> ：" + kongzhiqi);
//        ByteBuf lenBB = newIn.readBytes(2);
        // 数据包长度 两个字节
        long len = newIn.readShort();//lenBB.getShort(0);
        System.out.println("==长度=>>> ：" + len);
        // 数据包，（这里之所以要加连个字节,是因为最后两个字节是校验码）
        ByteBuf bodyBB = newIn.readBytes((int) (len + 2)); //
//        newIn.readByte
        String s = ByteBufUtil.hexDump(bodyBB);
        System.out.println("==body=>>> ：" + s);

//        newIn.resetReaderIndex();
//        newIn.resetWriterIndex();

        System.out.println("=全部==>>>:" + ByteBufUtil.hexDump(newIn));
        return newIn;
    }

    @Override
    protected long getUnadjustedFrameLength(ByteBuf buf, int offset, int length, ByteOrder order) {
//        （这里之所以要加2个字节,是因为最后两个字节是校验码）,所以必须在数据包长度基础上加上校验码的两个字节长度
        return super.getUnadjustedFrameLength(buf, offset, length, order) + 2;
    }
}
